home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / d_polyse.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  25KB  |  1,111 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // d_polyset.c: routines for drawing sets of polygons sharing the same
  21. // texture (used for Alias models)
  22.  
  23. #include "quakedef.h"
  24. #include "r_local.h"
  25. #include "d_local.h"
  26.  
  27. // TODO: put in span spilling to shrink list size
  28. // !!! if this is changed, it must be changed in d_polysa.s too !!!
  29. #define DPS_MAXSPANS            MAXHEIGHT+1    
  30.                                     // 1 extra for spanpackage that marks end
  31.  
  32. // !!! if this is changed, it must be changed in asm_draw.h too !!!
  33. typedef struct {
  34.     void            *pdest;
  35.     short            *pz;
  36.     int                count;
  37.     byte            *ptex;
  38.     int                sfrac, tfrac, light, zi;
  39. } spanpackage_t;
  40.  
  41. typedef struct {
  42.     int        isflattop;
  43.     int        numleftedges;
  44.     int        *pleftedgevert0;
  45.     int        *pleftedgevert1;
  46.     int        *pleftedgevert2;
  47.     int        numrightedges;
  48.     int        *prightedgevert0;
  49.     int        *prightedgevert1;
  50.     int        *prightedgevert2;
  51. } edgetable;
  52.  
  53. int    r_p0[6], r_p1[6], r_p2[6];
  54.  
  55. byte        *d_pcolormap;
  56.  
  57. int            d_aflatcolor;
  58. int            d_xdenom;
  59.  
  60. edgetable    *pedgetable;
  61.  
  62. edgetable    edgetables[12] = {
  63.     {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
  64.     {0, 2, r_p1, r_p0, r_p2,   1, r_p1, r_p2, NULL},
  65.     {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
  66.     {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
  67.     {0, 2, r_p0, r_p2, r_p1,   1, r_p0, r_p1, NULL},
  68.     {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
  69.     {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
  70.     {0, 2, r_p2, r_p1, r_p0,   1, r_p2, r_p0, NULL},
  71.     {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
  72.     {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
  73.     {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
  74.     {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
  75. };
  76.  
  77. static int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
  78. static int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
  79. static int r_zistepx, r_zistepy;
  80. static int d_aspancount, d_countextrastep;
  81.  
  82. static spanpackage_t            *a_spans;
  83. static spanpackage_t            *d_pedgespanpackage;
  84. static int                ystart;
  85. static byte                    *d_pdest, *d_ptex;
  86. static short                    *d_pz;
  87. static int                        d_sfrac, d_tfrac, d_light, d_zi;
  88. static int                        d_ptexextrastep, d_sfracextrastep;
  89. static int                        d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
  90. static int                        d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
  91. static int                        d_sfracbasestep, d_tfracbasestep;
  92. static int                        d_ziextrastep, d_zibasestep;
  93. static int                        d_pzextrastep, d_pzbasestep;
  94.  
  95. typedef struct {
  96.     int        quotient;
  97.     int        remainder;
  98. } adivtab_t;
  99.  
  100. static adivtab_t    adivtab[32*32] = {
  101. #include "adivtab.h"
  102. };
  103.  
  104. byte    *skintable[MAX_LBM_HEIGHT];
  105. int        skinwidth;
  106. byte    *skinstart;
  107.  
  108. void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);
  109. void D_PolysetCalcGradients (int skinwidth);
  110. void D_DrawSubdiv (void);
  111. void D_DrawNonSubdiv (void);
  112. void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);
  113. void D_PolysetSetEdgeTable (void);
  114. void D_RasterizeAliasPolySmooth (void);
  115. void D_PolysetScanLeftEdge (int height);
  116.  
  117. #if    !id386
  118.  
  119. /*
  120. ================
  121. D_PolysetDraw
  122. ================
  123. */
  124. void D_PolysetDraw (void)
  125. {
  126.     spanpackage_t    spans[DPS_MAXSPANS + 1 +
  127.             ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1];
  128.                         // one extra because of cache line pretouching
  129.  
  130.     a_spans = (spanpackage_t *)
  131.             (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
  132.  
  133.     if (r_affinetridesc.drawtype)
  134.     {
  135.         D_DrawSubdiv ();
  136.     }
  137.     else
  138.     {
  139.         D_DrawNonSubdiv ();
  140.     }
  141. }
  142.  
  143.  
  144. /*
  145. ================
  146. D_PolysetDrawFinalVerts
  147. ================
  148. */
  149. void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts)
  150. {
  151.     int        i, z;
  152.     short    *zbuf;
  153.  
  154.     for (i=0 ; i<numverts ; i++, fv++)
  155.     {
  156.     // valid triangle coordinates for filling can include the bottom and
  157.     // right clip edges, due to the fill rule; these shouldn't be drawn
  158.         if ((fv->v[0] < r_refdef.vrectright) &&
  159.             (fv->v[1] < r_refdef.vrectbottom))
  160.         {
  161.             z = fv->v[5]>>16;
  162.             zbuf = zspantable[fv->v[1]] + fv->v[0];
  163.             if (z >= *zbuf)
  164.             {
  165.                 int        pix;
  166.                 
  167.                 *zbuf = z;
  168.                 pix = skintable[fv->v[3]>>16][fv->v[2]>>16];
  169.                 pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ];
  170.                 d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix;
  171.             }
  172.         }
  173.     }
  174. }
  175.  
  176.  
  177. /*
  178. ================
  179. D_DrawSubdiv
  180. ================
  181. */
  182. void D_DrawSubdiv (void)
  183. {
  184.     mtriangle_t        *ptri;
  185.     finalvert_t        *pfv, *index0, *index1, *index2;
  186.     int                i;
  187.     int                lnumtriangles;
  188.  
  189.     pfv = r_affinetridesc.pfinalverts;
  190.     ptri = r_affinetridesc.ptriangles;
  191.     lnumtriangles = r_affinetridesc.numtriangles;
  192.  
  193.     for (i=0 ; i<lnumtriangles ; i++)
  194.     {
  195.         index0 = pfv + ptri[i].vertindex[0];
  196.         index1 = pfv + ptri[i].vertindex[1];
  197.         index2 = pfv + ptri[i].vertindex[2];
  198.  
  199.         if (((index0->v[1]-index1->v[1]) *
  200.              (index0->v[0]-index2->v[0]) -
  201.              (index0->v[0]-index1->v[0]) * 
  202.              (index0->v[1]-index2->v[1])) >= 0)
  203.         {
  204.             continue;
  205.         }
  206.  
  207.         d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
  208.  
  209.         if (ptri[i].facesfront)
  210.         {
  211.             D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
  212.         }
  213.         else
  214.         {
  215.             int        s0, s1, s2;
  216.  
  217.             s0 = index0->v[2];
  218.             s1 = index1->v[2];
  219.             s2 = index2->v[2];
  220.  
  221.             if (index0->flags & ALIAS_ONSEAM)
  222.                 index0->v[2] += r_affinetridesc.seamfixupX16;
  223.             if (index1->flags & ALIAS_ONSEAM)
  224.                 index1->v[2] += r_affinetridesc.seamfixupX16;
  225.             if (index2->flags & ALIAS_ONSEAM)
  226.                 index2->v[2] += r_affinetridesc.seamfixupX16;
  227.  
  228.             D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
  229.  
  230.             index0->v[2] = s0;
  231.             index1->v[2] = s1;
  232.             index2->v[2] = s2;
  233.         }
  234.     }
  235. }
  236.  
  237.  
  238. /*
  239. ================
  240. D_DrawNonSubdiv
  241. ================
  242. */
  243. void D_DrawNonSubdiv (void)
  244. {
  245.     mtriangle_t        *ptri;
  246.     finalvert_t        *pfv, *index0, *index1, *index2;
  247.     int                i;
  248.     int                lnumtriangles;
  249.  
  250.     pfv = r_affinetridesc.pfinalverts;
  251.     ptri = r_affinetridesc.ptriangles;
  252.     lnumtriangles = r_affinetridesc.numtriangles;
  253.  
  254.     for (i=0 ; i<lnumtriangles ; i++, ptri++)
  255.     {
  256.         index0 = pfv + ptri->vertindex[0];
  257.         index1 = pfv + ptri->vertindex[1];
  258.         index2 = pfv + ptri->vertindex[2];
  259.  
  260.         d_xdenom = (index0->v[1]-index1->v[1]) *
  261.                 (index0->v[0]-index2->v[0]) -
  262.                 (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]);
  263.  
  264.         if (d_xdenom >= 0)
  265.         {
  266.             continue;
  267.         }
  268.  
  269.         r_p0[0] = index0->v[0];        // u
  270.         r_p0[1] = index0->v[1];        // v
  271.         r_p0[2] = index0->v[2];        // s
  272.         r_p0[3] = index0->v[3];        // t
  273.         r_p0[4] = index0->v[4];        // light
  274.         r_p0[5] = index0->v[5];        // iz
  275.  
  276.         r_p1[0] = index1->v[0];
  277.         r_p1[1] = index1->v[1];
  278.         r_p1[2] = index1->v[2];
  279.         r_p1[3] = index1->v[3];
  280.         r_p1[4] = index1->v[4];
  281.         r_p1[5] = index1->v[5];
  282.  
  283.         r_p2[0] = index2->v[0];
  284.         r_p2[1] = index2->v[1];
  285.         r_p2[2] = index2->v[2];
  286.         r_p2[3] = index2->v[3];
  287.         r_p2[4] = index2->v[4];
  288.         r_p2[5] = index2->v[5];
  289.  
  290.         if (!ptri->facesfront)
  291.         {
  292.             if (index0->flags & ALIAS_ONSEAM)
  293.                 r_p0[2] += r_affinetridesc.seamfixupX16;
  294.             if (index1->flags & ALIAS_ONSEAM)
  295.                 r_p1[2] += r_affinetridesc.seamfixupX16;
  296.             if (index2->flags & ALIAS_ONSEAM)
  297.                 r_p2[2] += r_affinetridesc.seamfixupX16;
  298.         }
  299.  
  300.         D_PolysetSetEdgeTable ();
  301.         D_RasterizeAliasPolySmooth ();
  302.     }
  303. }
  304.  
  305.  
  306. /*
  307. ================
  308. D_PolysetRecursiveTriangle
  309. ================
  310. */
  311. void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3)
  312. {
  313.     int        *temp;
  314.     int        d;
  315.     int        new[6];
  316.     int        z;
  317.     short    *zbuf;
  318.  
  319.     d = lp2[0] - lp1[0];
  320.     if (d < -1 || d > 1)
  321.         goto split;
  322.     d = lp2[1] - lp1[1];
  323.     if (d < -1 || d > 1)
  324.         goto split;
  325.  
  326.     d = lp3[0] - lp2[0];
  327.     if (d < -1 || d > 1)
  328.         goto split2;
  329.     d = lp3[1] - lp2[1];
  330.     if (d < -1 || d > 1)
  331.         goto split2;
  332.  
  333.     d = lp1[0] - lp3[0];
  334.     if (d < -1 || d > 1)
  335.         goto split3;
  336.     d = lp1[1] - lp3[1];
  337.     if (d < -1 || d > 1)
  338.     {
  339. split3:
  340.         temp = lp1;
  341.         lp1 = lp3;
  342.         lp3 = lp2;
  343.         lp2 = temp;
  344.  
  345.         goto split;
  346.     }
  347.  
  348.     return;            // entire tri is filled
  349.  
  350. split2:
  351.     temp = lp1;
  352.     lp1 = lp2;
  353.     lp2 = lp3;
  354.     lp3 = temp;
  355.  
  356. split:
  357. // split this edge
  358.     new[0] = (lp1[0] + lp2[0]) >> 1;
  359.     new[1] = (lp1[1] + lp2[1]) >> 1;
  360.     new[2] = (lp1[2] + lp2[2]) >> 1;
  361.     new[3] = (lp1[3] + lp2[3]) >> 1;
  362.     new[5] = (lp1[5] + lp2[5]) >> 1;
  363.  
  364. // draw the point if splitting a leading edge
  365.     if (lp2[1] > lp1[1])
  366.         goto nodraw;
  367.     if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
  368.         goto nodraw;
  369.  
  370.  
  371.     z = new[5]>>16;
  372.     zbuf = zspantable[new[1]] + new[0];
  373.     if (z >= *zbuf)
  374.     {
  375.         int        pix;
  376.         
  377.         *zbuf = z;
  378.         pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]];
  379.         d_viewbuffer[d_scantable[new[1]] + new[0]] = pix;
  380.     }
  381.  
  382. nodraw:
  383. // recursively continue
  384.     D_PolysetRecursiveTriangle (lp3, lp1, new);
  385.     D_PolysetRecursiveTriangle (lp3, new, lp2);
  386. }
  387.  
  388. #endif    // !id386
  389.  
  390.  
  391. /*
  392. ================
  393. D_PolysetUpdateTables
  394. ================
  395. */
  396. void D_PolysetUpdateTables (void)
  397. {
  398.     int        i;
  399.     byte    *s;
  400.     
  401.     if (r_affinetridesc.skinwidth != skinwidth ||
  402.         r_affinetridesc.pskin != skinstart)
  403.     {
  404.         skinwidth = r_affinetridesc.skinwidth;
  405.         skinstart = r_affinetridesc.pskin;
  406.         s = skinstart;
  407.         for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
  408.             skintable[i] = s;
  409.     }
  410. }
  411.  
  412.  
  413. #if    !id386
  414.  
  415. /*
  416. ===================
  417. D_PolysetScanLeftEdge
  418. ====================
  419. */
  420. void D_PolysetScanLeftEdge (int height)
  421. {
  422.  
  423.     do
  424.     {
  425.         d_pedgespanpackage->pdest = d_pdest;
  426.         d_pedgespanpackage->pz = d_pz;
  427.         d_pedgespanpackage->count = d_aspancount;
  428.         d_pedgespanpackage->ptex = d_ptex;
  429.  
  430.         d_pedgespanpackage->sfrac = d_sfrac;
  431.         d_pedgespanpackage->tfrac = d_tfrac;
  432.  
  433.     // FIXME: need to clamp l, s, t, at both ends?
  434.         d_pedgespanpackage->light = d_light;
  435.         d_pedgespanpackage->zi = d_zi;
  436.  
  437.         d_pedgespanpackage++;
  438.  
  439.         errorterm += erroradjustup;
  440.         if (errorterm >= 0)
  441.         {
  442.             d_pdest += d_pdestextrastep;
  443.             d_pz += d_pzextrastep;
  444.             d_aspancount += d_countextrastep;
  445.             d_ptex += d_ptexextrastep;
  446.             d_sfrac += d_sfracextrastep;
  447.             d_ptex += d_sfrac >> 16;
  448.  
  449.             d_sfrac &= 0xFFFF;
  450.             d_tfrac += d_tfracextrastep;
  451.             if (d_tfrac & 0x10000)
  452.             {
  453.                 d_ptex += r_affinetridesc.skinwidth;
  454.                 d_tfrac &= 0xFFFF;
  455.             }
  456.             d_light += d_lightextrastep;
  457.             d_zi += d_ziextrastep;
  458.             errorterm -= erroradjustdown;
  459.         }
  460.         else
  461.         {
  462.             d_pdest += d_pdestbasestep;
  463.             d_pz += d_pzbasestep;
  464.             d_aspancount += ubasestep;
  465.             d_ptex += d_ptexbasestep;
  466.             d_sfrac += d_sfracbasestep;
  467.             d_ptex += d_sfrac >> 16;
  468.             d_sfrac &= 0xFFFF;
  469.             d_tfrac += d_tfracbasestep;
  470.             if (d_tfrac & 0x10000)
  471.             {
  472.                 d_ptex += r_affinetridesc.skinwidth;
  473.                 d_tfrac &= 0xFFFF;
  474.             }
  475.             d_light += d_lightbasestep;
  476.             d_zi += d_zibasestep;
  477.         }
  478.     } while (--height);
  479. }
  480.  
  481. #endif    // !id386
  482.  
  483.  
  484. /*
  485. ===================
  486. D_PolysetSetUpForLineScan
  487. ====================
  488. */
  489. void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
  490.         fixed8_t endvertu, fixed8_t endvertv)
  491. {
  492.     double        dm, dn;
  493.     int            tm, tn;
  494.     adivtab_t    *ptemp;
  495.  
  496. // TODO: implement x86 version
  497.  
  498.     errorterm = -1;
  499.  
  500.     tm = endvertu - startvertu;
  501.     tn = endvertv - startvertv;
  502.  
  503.     if (((tm <= 16) && (tm >= -15)) &&
  504.         ((tn <= 16) && (tn >= -15)))
  505.     {
  506.         ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
  507.         ubasestep = ptemp->quotient;
  508.         erroradjustup = ptemp->remainder;
  509.         erroradjustdown = tn;
  510.     }
  511.     else
  512.     {
  513.         dm = (double)tm;
  514.         dn = (double)tn;
  515.  
  516.         FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
  517.  
  518.         erroradjustdown = dn;
  519.     }
  520. }
  521.  
  522.  
  523. #if    !id386
  524.  
  525. /*
  526. ================
  527. D_PolysetCalcGradients
  528. ================
  529. */
  530. void D_PolysetCalcGradients (int skinwidth)
  531. {
  532.     float    xstepdenominv, ystepdenominv, t0, t1;
  533.     float    p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
  534.  
  535.     p00_minus_p20 = r_p0[0] - r_p2[0];
  536.     p01_minus_p21 = r_p0[1] - r_p2[1];
  537.     p10_minus_p20 = r_p1[0] - r_p2[0];
  538.     p11_minus_p21 = r_p1[1] - r_p2[1];
  539.  
  540.     xstepdenominv = 1.0 / (float)d_xdenom;
  541.  
  542.     ystepdenominv = -xstepdenominv;
  543.  
  544. // ceil () for light so positive steps are exaggerated, negative steps
  545. // diminished,  pushing us away from underflow toward overflow. Underflow is
  546. // very visible, overflow is very unlikely, because of ambient lighting
  547.     t0 = r_p0[4] - r_p2[4];
  548.     t1 = r_p1[4] - r_p2[4];
  549.     r_lstepx = (int)
  550.             ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
  551.     r_lstepy = (int)
  552.             ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
  553.  
  554.     t0 = r_p0[2] - r_p2[2];
  555.     t1 = r_p1[2] - r_p2[2];
  556.     r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  557.             xstepdenominv);
  558.     r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
  559.             ystepdenominv);
  560.  
  561.     t0 = r_p0[3] - r_p2[3];
  562.     t1 = r_p1[3] - r_p2[3];
  563.     r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  564.             xstepdenominv);
  565.     r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  566.             ystepdenominv);
  567.  
  568.     t0 = r_p0[5] - r_p2[5];
  569.     t1 = r_p1[5] - r_p2[5];
  570.     r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  571.             xstepdenominv);
  572.     r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  573.             ystepdenominv);
  574.  
  575. #if    id386
  576.     a_sstepxfrac = r_sstepx << 16;
  577.     a_tstepxfrac = r_tstepx << 16;
  578. #else
  579.     a_sstepxfrac = r_sstepx & 0xFFFF;
  580.     a_tstepxfrac = r_tstepx & 0xFFFF;
  581. #endif
  582.  
  583.     a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
  584. }
  585.  
  586. #endif    // !id386
  587.  
  588.  
  589. #if 0
  590. byte gelmap[256];
  591. void InitGel (byte *palette)
  592. {
  593.     int        i;
  594.     int        r;
  595.  
  596.     for (i=0 ; i<256 ; i++)
  597.     {
  598. //        r = (palette[i*3]>>4);
  599.         r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3);
  600.         gelmap[i] = /* 64 */ 0 + r;
  601.     }
  602. }
  603. #endif
  604.  
  605.  
  606. #if    !id386
  607.  
  608. /*
  609. ================
  610. D_PolysetDrawSpans8
  611. ================
  612. */
  613. void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage)
  614. {
  615.     int        lcount;
  616.     byte    *lpdest;
  617.     byte    *lptex;
  618.     int        lsfrac, ltfrac;
  619.     int        llight;
  620.     int        lzi;
  621.     short    *lpz;
  622.  
  623.     do
  624.     {
  625.         lcount = d_aspancount - pspanpackage->count;
  626.  
  627.         errorterm += erroradjustup;
  628.         if (errorterm >= 0)
  629.         {
  630.             d_aspancount += d_countextrastep;
  631.             errorterm -= erroradjustdown;
  632.         }
  633.         else
  634.         {
  635.             d_aspancount += ubasestep;
  636.         }
  637.  
  638.         if (lcount)
  639.         {
  640.             lpdest = pspanpackage->pdest;
  641.             lptex = pspanpackage->ptex;
  642.             lpz = pspanpackage->pz;
  643.             lsfrac = pspanpackage->sfrac;
  644.             ltfrac = pspanpackage->tfrac;
  645.             llight = pspanpackage->light;
  646.             lzi = pspanpackage->zi;
  647.  
  648.             do
  649.             {
  650.                 if ((lzi >> 16) >= *lpz)
  651.                 {
  652.                     *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)];
  653. // gel mapping                    *lpdest = gelmap[*lpdest];
  654.                     *lpz = lzi >> 16;
  655.                 }
  656.                 lpdest++;
  657.                 lzi += r_zistepx;
  658.                 lpz++;
  659.                 llight += r_lstepx;
  660.                 lptex += a_ststepxwhole;
  661.                 lsfrac += a_sstepxfrac;
  662.                 lptex += lsfrac >> 16;
  663.                 lsfrac &= 0xFFFF;
  664.                 ltfrac += a_tstepxfrac;
  665.                 if (ltfrac & 0x10000)
  666.                 {
  667.                     lptex += r_affinetridesc.skinwidth;
  668.                     ltfrac &= 0xFFFF;
  669.                 }
  670.             } while (--lcount);
  671.         }
  672.  
  673.         pspanpackage++;
  674.     } while (pspanpackage->count != -999999);
  675. }
  676. #endif    // !id386
  677.  
  678.  
  679. /*
  680. ================
  681. D_PolysetFillSpans8
  682. ================
  683. */
  684. void D_PolysetFillSpans8 (spanpackage_t *pspanpackage)
  685. {
  686.     int                color;
  687.  
  688. // FIXME: do z buffering
  689.  
  690.     color = d_aflatcolor++;
  691.  
  692.     while (1)
  693.     {
  694.         int        lcount;
  695.         byte    *lpdest;
  696.  
  697.         lcount = pspanpackage->count;
  698.  
  699.         if (lcount == -1)
  700.             return;
  701.  
  702.         if (lcount)
  703.         {
  704.             lpdest = pspanpackage->pdest;
  705.  
  706.             do
  707.             {
  708.                 *lpdest++ = color;
  709.             } while (--lcount);
  710.         }
  711.  
  712.         pspanpackage++;
  713.     }
  714. }
  715.  
  716. /*
  717. ================
  718. D_RasterizeAliasPolySmooth
  719. ================
  720. */
  721. void D_RasterizeAliasPolySmooth (void)
  722. {
  723.     int                initialleftheight, initialrightheight;
  724.     int                *plefttop, *prighttop, *pleftbottom, *prightbottom;
  725.     int                working_lstepx, originalcount;
  726.  
  727.     plefttop = pedgetable->pleftedgevert0;
  728.     prighttop = pedgetable->prightedgevert0;
  729.  
  730.     pleftbottom = pedgetable->pleftedgevert1;
  731.     prightbottom = pedgetable->prightedgevert1;
  732.  
  733.     initialleftheight = pleftbottom[1] - plefttop[1];
  734.     initialrightheight = prightbottom[1] - prighttop[1];
  735.  
  736. //
  737. // set the s, t, and light gradients, which are consistent across the triangle
  738. // because being a triangle, things are affine
  739. //
  740.     D_PolysetCalcGradients (r_affinetridesc.skinwidth);
  741.  
  742. //
  743. // rasterize the polygon
  744. //
  745.  
  746. //
  747. // scan out the top (and possibly only) part of the left edge
  748. //
  749.     d_pedgespanpackage = a_spans;
  750.  
  751.     ystart = plefttop[1];
  752.     d_aspancount = plefttop[0] - prighttop[0];
  753.  
  754.     d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
  755.             (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
  756. #if    id386
  757.     d_sfrac = (plefttop[2] & 0xFFFF) << 16;
  758.     d_tfrac = (plefttop[3] & 0xFFFF) << 16;
  759. #else
  760.     d_sfrac = plefttop[2] & 0xFFFF;
  761.     d_tfrac = plefttop[3] & 0xFFFF;
  762. #endif
  763.     d_light = plefttop[4];
  764.     d_zi = plefttop[5];
  765.  
  766.     d_pdest = (byte *)d_viewbuffer +
  767.             ystart * screenwidth + plefttop[0];
  768.     d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
  769.  
  770.     if (initialleftheight == 1)
  771.     {
  772.         d_pedgespanpackage->pdest = d_pdest;
  773.         d_pedgespanpackage->pz = d_pz;
  774.         d_pedgespanpackage->count = d_aspancount;
  775.         d_pedgespanpackage->ptex = d_ptex;
  776.  
  777.         d_pedgespanpackage->sfrac = d_sfrac;
  778.         d_pedgespanpackage->tfrac = d_tfrac;
  779.  
  780.     // FIXME: need to clamp l, s, t, at both ends?
  781.         d_pedgespanpackage->light = d_light;
  782.         d_pedgespanpackage->zi = d_zi;
  783.  
  784.         d_pedgespanpackage++;
  785.     }
  786.     else
  787.     {
  788.         D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
  789.                               pleftbottom[0], pleftbottom[1]);
  790.  
  791.     #if    id386
  792.         d_pzbasestep = (d_zwidth + ubasestep) << 1;
  793.         d_pzextrastep = d_pzbasestep + 2;
  794.     #else
  795.         d_pzbasestep = d_zwidth + ubasestep;
  796.         d_pzextrastep = d_pzbasestep + 1;
  797.     #endif
  798.  
  799.         d_pdestbasestep = screenwidth + ubasestep;
  800.         d_pdestextrastep = d_pdestbasestep + 1;
  801.  
  802.     // TODO: can reuse partial expressions here
  803.  
  804.     // for negative steps in x along left edge, bias toward overflow rather than
  805.     // underflow (sort of turning the floor () we did in the gradient calcs into
  806.     // ceil (), but plus a little bit)
  807.         if (ubasestep < 0)
  808.             working_lstepx = r_lstepx - 1;
  809.         else
  810.             working_lstepx = r_lstepx;
  811.  
  812.         d_countextrastep = ubasestep + 1;
  813.         d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
  814.                 ((r_tstepy + r_tstepx * ubasestep) >> 16) *
  815.                 r_affinetridesc.skinwidth;
  816.     #if    id386
  817.         d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
  818.         d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
  819.     #else
  820.         d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
  821.         d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
  822.     #endif
  823.         d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
  824.         d_zibasestep = r_zistepy + r_zistepx * ubasestep;
  825.  
  826.         d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
  827.                 ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
  828.                 r_affinetridesc.skinwidth;
  829.     #if    id386
  830.         d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
  831.         d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
  832.     #else
  833.         d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
  834.         d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
  835.     #endif
  836.         d_lightextrastep = d_lightbasestep + working_lstepx;
  837.         d_ziextrastep = d_zibasestep + r_zistepx;
  838.  
  839.         D_PolysetScanLeftEdge (initialleftheight);
  840.     }
  841.  
  842. //
  843. // scan out the bottom part of the left edge, if it exists
  844. //
  845.     if (pedgetable->numleftedges == 2)
  846.     {
  847.         int        height;
  848.  
  849.         plefttop = pleftbottom;
  850.         pleftbottom = pedgetable->pleftedgevert2;
  851.  
  852.         height = pleftbottom[1] - plefttop[1];
  853.  
  854. // TODO: make this a function; modularize this function in general
  855.  
  856.         ystart = plefttop[1];
  857.         d_aspancount = plefttop[0] - prighttop[0];
  858.         d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
  859.                 (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
  860.         d_sfrac = 0;
  861.         d_tfrac = 0;
  862.         d_light = plefttop[4];
  863.         d_zi = plefttop[5];
  864.  
  865.         d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
  866.         d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
  867.  
  868.         if (height == 1)
  869.         {
  870.             d_pedgespanpackage->pdest = d_pdest;
  871.             d_pedgespanpackage->pz = d_pz;
  872.             d_pedgespanpackage->count = d_aspancount;
  873.             d_pedgespanpackage->ptex = d_ptex;
  874.  
  875.             d_pedgespanpackage->sfrac = d_sfrac;
  876.             d_pedgespanpackage->tfrac = d_tfrac;
  877.  
  878.         // FIXME: need to clamp l, s, t, at both ends?
  879.             d_pedgespanpackage->light = d_light;
  880.             d_pedgespanpackage->zi = d_zi;
  881.  
  882.             d_pedgespanpackage++;
  883.         }
  884.         else
  885.         {
  886.             D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
  887.                                   pleftbottom[0], pleftbottom[1]);
  888.  
  889.             d_pdestbasestep = screenwidth + ubasestep;
  890.             d_pdestextrastep = d_pdestbasestep + 1;
  891.  
  892.     #if    id386
  893.             d_pzbasestep = (d_zwidth + ubasestep) << 1;
  894.             d_pzextrastep = d_pzbasestep + 2;
  895.     #else
  896.             d_pzbasestep = d_zwidth + ubasestep;
  897.             d_pzextrastep = d_pzbasestep + 1;
  898.     #endif
  899.  
  900.             if (ubasestep < 0)
  901.                 working_lstepx = r_lstepx - 1;
  902.             else
  903.                 working_lstepx = r_lstepx;
  904.  
  905.             d_countextrastep = ubasestep + 1;
  906.             d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
  907.                     ((r_tstepy + r_tstepx * ubasestep) >> 16) *
  908.                     r_affinetridesc.skinwidth;
  909.     #if    id386
  910.             d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
  911.             d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
  912.     #else
  913.             d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
  914.             d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
  915.     #endif
  916.             d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
  917.             d_zibasestep = r_zistepy + r_zistepx * ubasestep;
  918.  
  919.             d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
  920.                     ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
  921.                     r_affinetridesc.skinwidth;
  922.     #if    id386
  923.             d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
  924.             d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
  925.     #else
  926.             d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
  927.             d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
  928.     #endif
  929.             d_lightextrastep = d_lightbasestep + working_lstepx;
  930.             d_ziextrastep = d_zibasestep + r_zistepx;
  931.  
  932.             D_PolysetScanLeftEdge (height);
  933.         }
  934.     }
  935.  
  936. // scan out the top (and possibly only) part of the right edge, updating the
  937. // count field
  938.     d_pedgespanpackage = a_spans;
  939.  
  940.     D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
  941.                           prightbottom[0], prightbottom[1]);
  942.     d_aspancount = 0;
  943.     d_countextrastep = ubasestep + 1;
  944.     originalcount = a_spans[initialrightheight].count;
  945.     a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
  946.     D_PolysetDrawSpans8 (a_spans);
  947.  
  948. // scan out the bottom part of the right edge, if it exists
  949.     if (pedgetable->numrightedges == 2)
  950.     {
  951.         int                height;
  952.         spanpackage_t    *pstart;
  953.  
  954.         pstart = a_spans + initialrightheight;
  955.         pstart->count = originalcount;
  956.  
  957.         d_aspancount = prightbottom[0] - prighttop[0];
  958.  
  959.         prighttop = prightbottom;
  960.         prightbottom = pedgetable->prightedgevert2;
  961.  
  962.         height = prightbottom[1] - prighttop[1];
  963.  
  964.         D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
  965.                               prightbottom[0], prightbottom[1]);
  966.  
  967.         d_countextrastep = ubasestep + 1;
  968.         a_spans[initialrightheight + height].count = -999999;
  969.                                             // mark end of the spanpackages
  970.         D_PolysetDrawSpans8 (pstart);
  971.     }
  972. }
  973.  
  974.  
  975. /*
  976. ================
  977. D_PolysetSetEdgeTable
  978. ================
  979. */
  980. void D_PolysetSetEdgeTable (void)
  981. {
  982.     int            edgetableindex;
  983.  
  984.     edgetableindex = 0;    // assume the vertices are already in
  985.                         //  top to bottom order
  986.  
  987. //
  988. // determine which edges are right & left, and the order in which
  989. // to rasterize them
  990. //
  991.     if (r_p0[1] >= r_p1[1])
  992.     {
  993.         if (r_p0[1] == r_p1[1])
  994.         {
  995.             if (r_p0[1] < r_p2[1])
  996.                 pedgetable = &edgetables[2];
  997.             else
  998.                 pedgetable = &edgetables[5];
  999.  
  1000.             return;
  1001.         }
  1002.         else
  1003.         {
  1004.             edgetableindex = 1;
  1005.         }
  1006.     }
  1007.  
  1008.     if (r_p0[1] == r_p2[1])
  1009.     {
  1010.         if (edgetableindex)
  1011.             pedgetable = &edgetables[8];
  1012.         else
  1013.             pedgetable = &edgetables[9];
  1014.  
  1015.         return;
  1016.     }
  1017.     else if (r_p1[1] == r_p2[1])
  1018.     {
  1019.         if (edgetableindex)
  1020.             pedgetable = &edgetables[10];
  1021.         else
  1022.             pedgetable = &edgetables[11];
  1023.  
  1024.         return;
  1025.     }
  1026.  
  1027.     if (r_p0[1] > r_p2[1])
  1028.         edgetableindex += 2;
  1029.  
  1030.     if (r_p1[1] > r_p2[1])
  1031.         edgetableindex += 4;
  1032.  
  1033.     pedgetable = &edgetables[edgetableindex];
  1034. }
  1035.  
  1036.  
  1037. #if 0
  1038.  
  1039. void D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
  1040. {
  1041.     int        d;
  1042.     int        new[6];
  1043.     int     ofs;
  1044.     
  1045.     d = lp2[0] - lp1[0];
  1046.     if (d < -1 || d > 1)
  1047.         goto split;
  1048.     d = lp2[1] - lp1[1];
  1049.     if (d < -1 || d > 1)
  1050.         goto split;
  1051.  
  1052.     return;    // line is completed
  1053.  
  1054. split:
  1055. // split this edge
  1056.     new[0] = (lp1[0] + lp2[0]) >> 1;
  1057.     new[1] = (lp1[1] + lp2[1]) >> 1;
  1058.     new[5] = (lp1[5] + lp2[5]) >> 1;
  1059.     new[2] = (lp1[2] + lp2[2]) >> 1;
  1060.     new[3] = (lp1[3] + lp2[3]) >> 1;
  1061.     new[4] = (lp1[4] + lp2[4]) >> 1;
  1062.  
  1063. // draw the point
  1064.     ofs = d_scantable[new[1]] + new[0];
  1065.     if (new[5] > d_pzbuffer[ofs])
  1066.     {
  1067.         int        pix;
  1068.         
  1069.         d_pzbuffer[ofs] = new[5];
  1070.         pix = skintable[new[3]>>16][new[2]>>16];
  1071. //        pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)];
  1072.         d_viewbuffer[ofs] = pix;
  1073.     }
  1074.  
  1075. // recursively continue
  1076.     D_PolysetRecursiveDrawLine (lp1, new);
  1077.     D_PolysetRecursiveDrawLine (new, lp2);
  1078. }
  1079.  
  1080. void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
  1081. {
  1082.     int        d;
  1083.     int        new[4];
  1084.     
  1085.     d = lp2[0] - lp1[0];
  1086.     if (d < -1 || d > 1)
  1087.         goto split;
  1088.     d = lp2[1] - lp1[1];
  1089.     if (d < -1 || d > 1)
  1090.         goto split;
  1091.     return;
  1092.  
  1093. split:
  1094. // split this edge
  1095.     new[0] = (lp1[0] + lp2[0]) >> 1;
  1096.     new[1] = (lp1[1] + lp2[1]) >> 1;
  1097.     new[5] = (lp1[5] + lp2[5]) >> 1;
  1098.     new[2] = (lp1[2] + lp2[2]) >> 1;
  1099.     new[3] = (lp1[3] + lp2[3]) >> 1;
  1100.     new[4] = (lp1[4] + lp2[4]) >> 1;
  1101.  
  1102.     D_PolysetRecursiveDrawLine (new, lp3);
  1103.  
  1104. // recursively continue
  1105.     D_PolysetRecursiveTriangle (lp1, new, lp3);
  1106.     D_PolysetRecursiveTriangle (new, lp2, lp3);
  1107. }
  1108.  
  1109. #endif
  1110.  
  1111.